import { isNull, showSuccess, clone, clog, showError } from '/@/utils';
import { enumCode } from '/@/const';
import { useConfirmDialog } from '/@/hooks';
import { InvYueXueApi, InvYueXueMingXi, InvYueXueOutput } from '/@/api/inv/InvYueXue';
import { loginInfo } from '/@/stores/baseInfo';
import { getXueYePinZhongInfo } from '/@/stores/baseInfo';
import { ElMessageBox } from 'element-plus';
import { XieYiYiYuanChuKuApi, BasYueXueYuJingOutputAndYueXueLian } from '/@/api/inv/invXieYiYiYuanChuKu';

export const billPanelRef = ref();
export const formRef = ref();
export const formMingXiRef = ref();
export const listRef = ref();
export const editPageRef = ref();

const initCtx = () => ({
	isEdit: false,
	loading: false,
	zhuBiao: { danJuLeiXing: '血液预约', dingXueYiYuanId: loginInfo.value.yuanQuId, dingXueYiYuan: loginInfo.value.yuanQuName } as InvYueXueOutput,
	mingXiList: [] as InvYueXueMingXi[],
	mingXi: { rhD: '+', danWei: '' } as InvYueXueMingXi,
	yueXueYuJingList: [] as BasYueXueYuJingOutputAndYueXueLian[],

});

export const ctx = reactive(initCtx()); // 使用 reactive 初始化

// 清空表单数据，将实体值 ctx 初始化为默认值，并让扫码框获得焦点
export const newZhuBiao = () => {
	//实体值ctx初始化
	Object.assign(ctx, initCtx());
	getYuJingShuju();
	ctx.isEdit = true;
};

// 加载单据，根据传入的单据信息调用接口获取数据并更新 ctx 中的主表和明细列表
export const loadZhuBiao = async (zhuBiao: InvYueXueOutput) => {
	if (isNull(zhuBiao) || isNull(zhuBiao.id)) {
		return;
	}
	//调用接口获取数据
	ctx.loading = true
	var res = await InvYueXueApi.get(zhuBiao.id).finally(() => ctx.loading = false);
	ctx.zhuBiao = res.zhuBiao;
	ctx.mingXiList = res.mingXiList;
	getYuJingShuju();

	formRef.value.resetFields();
	ctx.isEdit = false;
};

// 提交单据，先进行表单验证，根据单据是否有 ID 决定新增或处理主表，操作成功后关闭页面
export const submit = async () => {
	if (ctx.loading) return
	// 表单验证
	const validate = await formRef?.value?.validate();
	if (!validate) return;
	if (ctx.mingXiList.length === 0) {
		showError('明细不能为空');
		return;
	}
	const isContinue = await checkIsOverYuJing()
	if (!isContinue) {
		return;
	}

	if (isNull(ctx.zhuBiao.id)) {
		// 新增
		ctx.zhuBiao.danJuZhuangTai = enumCode.Djzt.待审核;
		ctx.loading = true
		ctx.zhuBiao = await InvYueXueApi.add({ ...ctx.zhuBiao, mingXiList: ctx.mingXiList }).finally(() => ctx.loading = false);
	} else {
		// 修改
		// 不能修改明细,只能修改作废主表
	}
	showSuccess();
	ctx.isEdit = false;

	close();
};

// 作废单据，若单据状态为待审核，确认后调用接口作废并更新单据状态
export const cancel = async () => {
	if (ctx.zhuBiao.danJuZhuangTai === enumCode.Djzt.待审核) {
		useConfirmDialog('确认作废吗?').then(async () => {
			await InvYueXueApi.cancel({ id: ctx.zhuBiao.id });
			ctx.zhuBiao.danJuZhuangTai = enumCode.Djzt.已作废;
			showSuccess('已作废');
		});
	} else {
		showError('单据状态不是待审核，不能作废');
	}
};

// 添加明细，先进行表单验证，检查品种是否重复，计算小计后添加到明细列表并重置明细表单
export const addMingXi = async () => {
	// 表单验证
	const validate = await formMingXiRef?.value?.validate();
	if (!validate) return;

	//每个品种只能添加一行
	for (const item of ctx.mingXiList) {
		if (item.xueYePinZhong == ctx.mingXi.xueYePinZhong && item.rhD == ctx.mingXi.rhD) {
			showError('该品种已经添加过了');
			return;
		}
	}
	// 计算小计
	if (!calcXiaoJi(ctx.mingXi)) {
		return;
	}
	ctx.mingXiList.push(clone(ctx.mingXi));
	ctx.mingXi = initCtx().mingXi;
};

// 查看明细
export const showMingXi = (row: InvYueXueMingXi) => {
	editPageRef.value.open(row);
};

// 修改血液信息，计算小计后找到匹配项并更新明细列表中的数据
export const updateMingXi = (row: any) => {
	clog('updateMingXi', row);
	if (!calcXiaoJi(row)) {
		return;
	}
	// 找到要修改的项的索引
	const index = ctx.mingXiList.findIndex((item: InvYueXueMingXi) => item.xueYePinZhong === row.xueYePinZhong && item.rhD === row.rhD);
	if (index !== -1) {
		// 直接修改数组中的对象
		ctx.mingXiList[index] = { ...ctx.mingXiList[index], ...row };
		showSuccess('已修改');
	} else {
		showError('未找到匹配的项');
	}
};

// 计算小计
const calcXiaoJi = (mingXi: InvYueXueMingXi) => {
	mingXi.rongLiangA = isNaN(mingXi.rongLiangA) ? 0 : mingXi.rongLiangA;
	mingXi.rongLiangB = isNaN(mingXi.rongLiangB) ? 0 : mingXi.rongLiangB;
	mingXi.rongLiangO = isNaN(mingXi.rongLiangO) ? 0 : mingXi.rongLiangO;
	mingXi.rongLiangAB = isNaN(mingXi.rongLiangAB) ? 0 : mingXi.rongLiangAB;
	mingXi.xiaoJi = Number(mingXi.rongLiangA) + Number(mingXi.rongLiangB) + Number(mingXi.rongLiangO) + Number(mingXi.rongLiangAB);
	clog('xiaoJi', mingXi.xiaoJi);
	if (!(mingXi.xiaoJi > 0)) {
		showError('订血量不能为0');
		return false;
	} else {
		return true;
	}
};

// 删除明细，从明细列表中过滤掉指定行并提示删除成功
export const deleteMingXi = (row: any) => {
	// 找到要删除的项的索引
	ctx.mingXiList = ctx.mingXiList.filter((item) => item != row);
	showSuccess('已删除');
};

// 处理品种变化，根据选择的血液品种更新明细表单中的单位信息
export const handlePinZhongChange = () => {
	let pinZhong = getXueYePinZhongInfo(ctx.mingXi.xueYePinZhong);
	ctx.mingXi.danWei = pinZhong?.danWei ?? '';
};

// 打印单据，目前打印功能注释未启用
export const print = () => {
	// billPanelRef.value.printWeb('billno', 'detail');
	// showSuccess('打印');
};
//#region 约血预警值处理
/** 获取预警数据 */
export const getYuJingShuju = () => {
	XieYiYiYuanChuKuApi.checkYuJingShuJu({ dingXueYiYuanId: loginInfo.value.yuanQuId, shiJian: new Date() }).then((res) => {
		// 过滤掉预警值、已出库量均为0或者空的数据
		const filteredList = res.filter((item) => {
			// 使用 Object.keys 和 some 方法检查对象是否有符合条件的属性
			return Object.keys(item).some((key) => {
				// 检查属性名是否以 yuJingZhi 或 chuKuLiang 开头，并且属性值存在
				return (key.startsWith('yuJingZhi') || key.startsWith('chuKuLiang')) && item[key];
			});
		});
		ctx.yueXueYuJingList = filteredList;
	});
}
/** 已约血量到达预警值，对应单元格显示红色  */
export const yuJingCellStyle = ({ row, column }: { row: any, column: any }) => {
	const prop = column.property;
	if (!prop) return {}; // 跳过无property的列

	let yuJingValue: number | undefined;
	let chuKuValue: number | undefined;

	// 处理预警值列（如yuJingZhiA）和已约血量列（如chuKuLiangA）
	if (prop.startsWith('yuJingZhi')) {
		// 预警值列：获取对应已约血量值（如yuJingZhiA -> chuKuLiangA）
		const yueXueProp = prop.replace('yuJingZhi', 'chuKuLiang');
		yuJingValue = row[prop];
		chuKuValue = row[yueXueProp];
	} else if (prop.startsWith('chuKuLiang')) {
		// 已约血量列：获取对应预警值（如chuKuLiangA -> yuJingZhiA）
		const yuJingProp = prop.replace('chuKuLiang', 'yuJingZhi');
		yuJingValue = row[yuJingProp];
		chuKuValue = row[prop];
	} else {
		return {}; // 非目标列不处理
	}

	// 预警值存在且已约血量≥预警值时显示红色背景
	if (yuJingValue !== null && yuJingValue !== undefined
		&& chuKuValue !== null && chuKuValue !== undefined
		&& chuKuValue >= yuJingValue) {
		return { backgroundColor: '#ff4d4f' };
	}
	return {};
};

/** 获取已约血量超过预警值的列表 */
const checkIsOverYuJing = async () => {
	// 定义血型数组，方便后续循环处理
	const bloodTypes = ['A', 'B', 'O', 'AB'];

	// 存储每个大类每个血型的本次约血量
	const bloodTypeToVolumeMap = new Map<string, { [key: string]: number }>();

	// 遍历明细列表，累加每个大类每个血型的本次约血量
	ctx.mingXiList.forEach((item) => {
		const daLei = getXueYePinZhongInfo(item.xueYePinZhong)?.daLei;
		if (!daLei) return;

		bloodTypeToVolumeMap.set(
			daLei,
			bloodTypes.reduce((acc, type) => {
				acc[type] = (acc[type] || 0) + (item[`rongLiang${type}`] || 0);
				return acc;
			}, bloodTypeToVolumeMap.get(daLei) || { A: 0, B: 0, O: 0, AB: 0 })
		);
	});

	// 存储满足条件的大类和血型信息
	const overYuJingInfo: { daLei: string; bloodType: string }[] = [];

	// 遍历预警列表，检查哪些大类的什么血型的预警值不为空且已出库量+本次约血量>=预警值
	ctx.yueXueYuJingList.forEach((item) => {
		const { daLei } = item;
		const benCiYueXueLiang = bloodTypeToVolumeMap.get(daLei) || { A: 0, B: 0, O: 0, AB: 0 };

		bloodTypes.forEach((type) => {
			const yuJingZhi = item[`yuJingZhi${type}`];
			const chuKuLiang = item[`chuKuLiang${type}`] ?? 0;
			if (yuJingZhi !== null && yuJingZhi !== undefined && (benCiYueXueLiang[type] + chuKuLiang) >= yuJingZhi) {
				overYuJingInfo.push({ daLei, bloodType: type });
			}
		});
	});

	// 生成提示消息
	const message = overYuJingInfo.length > 0
		? `血液大类<strong>${Array.from(
			overYuJingInfo.reduce((map, info) => {
				const arr = map.get(info.daLei) || [];
				arr.push(`${info.bloodType}型`);
				map.set(info.daLei, arr);
				return map;
			}, new Map<string, string[]>())
		).map(([daLei, bloodTypes]) => `${daLei}: ${bloodTypes.join('、')}`).join('， ')}</strong>本月累计出库量+本次约血量已达预警值, 是否继续约血`
		: '';

	if (message) {
		try {
			await ElMessageBox.confirm(message, '注意', {
				confirmButtonText: '是',
				cancelButtonText: '否',
				type: 'warning',
				closeOnClickModal: false,
				closeOnPressEscape: false,
				dangerouslyUseHTMLString: true,
			});
			return true;
		} catch {
			return false;
		}
	}

	return true;
}
//#endregion